<html>
<head>
<title>firstworks   Programming with Rudiments using the signal class</title>
<link href="../css/styles.css" rel="stylesheet">
</head>
<body>

<span class="heading">Using the signal classes</span><br><br>

<p>Signals allow one processes to interrupt the execution of another process.</p>

<p>Signal handlers allow processes to intercept and react to the signals sent to them.</p>

<p>Rudiments provides 3 classes for working with signals: <a href="../classes/html/classsignalset.html">signalset</a>, <a href="../classes/html/classsignalmanager.html">signalmanager</a> and <a href="../classes/html/classsignalhandler.html">signalhandler</a>.

<p>A signal set is just a collection of signals.  The <a href="../classes/html/classsignalset.html">signalset class</a> allows a programmer to build up a collection of signals.</p>

<p>The <a href="../classes/html/classsignalmanager.html">signalmanager class</a> provides methods for sending signals, ignoring signals, waiting for signals and examining blocked signals.</p>

<p>The <a href="../classes/html/classsignalhandler.html">signalhandler class</a> provides methods for catching and handling signals.</p>

<p>This program illustrates the use of all three classes.</p>

<blockquote class="code">

<script type='text/javascript'>
<!--

-->
</script>
<font face="monospace">
<font color="#0000ff">// Copyright (c) 2001&nbsp;&nbsp;David Muse</font><br>
<font color="#0000ff">// See the file COPYING for more information</font><br>
<br>
<font color="#800080">#include&nbsp;</font><font color="#ff00ff">&lt;rudiments/signalclasses.h&gt;</font><br>
<font color="#800080">#include&nbsp;</font><font color="#ff00ff">&lt;rudiments/stdio.h&gt;</font><br>
<br>
<font color="#2e8b57"><b>bool</b></font>&nbsp;&nbsp;&nbsp;&nbsp;gotsigterm=<font color="#ff00ff">false</font>;<br>
<br>
<font color="#2e8b57"><b>void</b></font>&nbsp;handleSigterm(<font color="#2e8b57"><b>int32_t</b></font>&nbsp;sig) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stdoutput.printf(<font color="#ff00ff">&quot;Got a SIGTERM!</font><font color="#6a5acd">\n</font><font color="#ff00ff">&quot;</font>);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gotsigterm=<font color="#ff00ff">true</font>;<br>
}<br>
<br>
<font color="#800080">#ifdef SIGALRM</font><br>
<font color="#2e8b57"><b>void</b></font>&nbsp;handleAlarm(<font color="#2e8b57"><b>int32_t</b></font>&nbsp;sig) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stdoutput.printf(<font color="#ff00ff">&quot;alarm!</font><font color="#6a5acd">\n</font><font color="#ff00ff">&quot;</font>);<br>
}<br>
<font color="#800080">#endif</font><br>
<br>
<font color="#2e8b57"><b>int</b></font>&nbsp;main(<font color="#2e8b57"><b>int</b></font>&nbsp;argc,&nbsp;<font color="#2e8b57"><b>const</b></font>&nbsp;<font color="#2e8b57"><b>char</b></font>&nbsp;**argv) {<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">// ignore all signals except SIGTERM and SIGALRM</font><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;signalset&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ignoreset;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ignoreset.addAllSignals();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ignoreset.removeSignal(<font color="#ff00ff">SIGTERM</font>);<br>
<font color="#800080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#ifdef SIGALRM</font><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ignoreset.removeSignal(<font color="#ff00ff">SIGALRM</font>);<br>
<font color="#800080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#endif</font><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;signalmanager::ignoreSignals(&amp;ignoreset);<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">// run handleSigterm() when a SIGTERM is received</font><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;signalhandler&nbsp;&nbsp; termhandler;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;termhandler.setHandler(handleSigterm);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;termhandler.handleSignal(<font color="#ff00ff">SIGTERM</font>);<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">// run handleAlarm() when a SIGALRM is received</font><br>
<font color="#800080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#ifdef SIGALRM</font><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;signalhandler&nbsp;&nbsp; alarmhandler;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alarmhandler.setHandler(handleAlarm);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alarmhandler.handleSignal(<font color="#ff00ff">SIGALRM</font>);<br>
<font color="#800080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#endif</font><br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">// Loop forever, waiting to receive a signal that we are not ignoring.</font><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;signalmanager::alarm(<font color="#ff00ff">2</font>);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#a52a2a"><b>while</b></font>&nbsp;(!gotsigterm) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;signalmanager::waitForSignals(&amp;ignoreset);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;signalmanager::alarm(<font color="#ff00ff">2</font>);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
}<br>
</font>
<!-- vim: set foldmethod=manual : -->
</blockquote>

<p>It should print out "alarm!" every 2 seconds and, if killed, should print out "Got a SIGTERM!" before exiting.  If killed with a signal other than SIGTERM (the default), then it will ignore the signal.</p>

<p>Windows systems don't have signals or the <i>kill</i> program.  Signals are more-or-less simulated on Windows platforms though, and the following program provides an approximation of the <i>kill</i> program as found on unix-like systems, that should work on Windows.</p>

<blockquote class="code">

<script type='text/javascript'>
<!--

-->
</script>
<font face="monospace">
<font color="#800080">#include&nbsp;</font><font color="#ff00ff">&lt;rudiments/process.h&gt;</font><br>
<font color="#800080">#include&nbsp;</font><font color="#ff00ff">&lt;rudiments/charstring.h&gt;</font><br>
<font color="#800080">#include&nbsp;</font><font color="#ff00ff">&lt;rudiments/error.h&gt;</font><br>
<font color="#800080">#include&nbsp;</font><font color="#ff00ff">&lt;rudiments/stdio.h&gt;</font><br>
<br>
<font color="#2e8b57"><b>int</b></font>&nbsp;main(<font color="#2e8b57"><b>int</b></font>&nbsp;argc,&nbsp;<font color="#2e8b57"><b>const</b></font>&nbsp;<font color="#2e8b57"><b>char</b></font>&nbsp;**argv) {<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#a52a2a"><b>if</b></font>&nbsp;(argc&lt;<font color="#ff00ff">3</font>) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stdoutput.printf(<font color="#ff00ff">&quot;usage: kill signal processid</font><font color="#6a5acd">\n</font><font color="#ff00ff">&quot;</font>);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;process::exit(<font color="#ff00ff">1</font>);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#2e8b57"><b>int32_t</b></font>&nbsp;sig=<font color="#ff00ff">SIGTERM</font>;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#a52a2a"><b>if</b></font>&nbsp;(!charstring::compare(argv[<font color="#ff00ff">1</font>],<font color="#ff00ff">&quot;SIGINT&quot;</font>)) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sig=<font color="#ff00ff">SIGINT</font>;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<font color="#a52a2a"><b>else</b></font>&nbsp;<font color="#a52a2a"><b>if</b></font>&nbsp;(!charstring::compare(argv[<font color="#ff00ff">1</font>],<font color="#ff00ff">&quot;SIGABRT&quot;</font>)) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sig=<font color="#ff00ff">SIGABRT</font>;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<font color="#a52a2a"><b>else</b></font>&nbsp;<font color="#a52a2a"><b>if</b></font>&nbsp;(!charstring::compare(argv[<font color="#ff00ff">1</font>],<font color="#ff00ff">&quot;SIGFPE&quot;</font>)) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sig=<font color="#ff00ff">SIGFPE</font>;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<font color="#a52a2a"><b>else</b></font>&nbsp;<font color="#a52a2a"><b>if</b></font>&nbsp;(!charstring::compare(argv[<font color="#ff00ff">1</font>],<font color="#ff00ff">&quot;SIGILL&quot;</font>)) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sig=<font color="#ff00ff">SIGILL</font>;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<font color="#a52a2a"><b>else</b></font>&nbsp;<font color="#a52a2a"><b>if</b></font>&nbsp;(!charstring::compare(argv[<font color="#ff00ff">1</font>],<font color="#ff00ff">&quot;SIGSEGV&quot;</font>)) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sig=<font color="#ff00ff">SIGSEGV</font>;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<font color="#a52a2a"><b>else</b></font>&nbsp;<font color="#a52a2a"><b>if</b></font>&nbsp;(!charstring::compare(argv[<font color="#ff00ff">1</font>],<font color="#ff00ff">&quot;SIGKILL&quot;</font>)) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sig=<font color="#ff00ff">SIGKILL</font>;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pid_t&nbsp;&nbsp; pid=charstring::toInteger(argv[<font color="#ff00ff">2</font>]);<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#a52a2a"><b>if</b></font>&nbsp;(!process::sendSignal(pid,sig)) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stdoutput.printf(<font color="#ff00ff">&quot;kill failed:&nbsp;</font><font color="#6a5acd">%s</font><font color="#6a5acd">\n</font><font color="#ff00ff">&quot;</font>,error::getErrorString());<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;process::exit(<font color="#ff00ff">1</font>);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;process::exit(<font color="#ff00ff">0</font>);<br>
}<br>
</font>
<!-- vim: set foldmethod=manual : -->
</blockquote>

</body>
</html>
